home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / src / mplayer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  7.7 KB  |  303 lines  |  [TEXT/R*ch]

  1. /*    SCCS Id: @(#)mplayer.c    3.1    93/03/14    */
  2. /*    Copyright (c) Izchak Miller, 1992.              */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6.  
  7. static const char *NDECL(dev_name);
  8. static void FDECL(get_mplname, (struct monst *, char *));
  9. static void FDECL(mk_mplayer_armor, (struct monst *, int, int));
  10.  
  11. /* These are the names of those who
  12.  * contributed to the development of NetHack 3.1.
  13.  *
  14.  * Keep in alphabetical order within teams.
  15.  * Same first name is entered once within each team.
  16.  */
  17. static const char *developers[] = {
  18.     /* devteam */
  19.     "Dave", "Dean", "Eric", "Izchak", "Janet", "Jessie",
  20.     "Ken", "Kevin", "Matt", "Mike", "Pat", "Steve", "Timo",
  21.     /* PC team */
  22.     "Bill", "Carl", "John", "Kevin", "Mike", "Norm", "Paul",
  23.     "Stephen", "Steve",
  24.     /* Amiga team */
  25.     "Greg", "Gregg", "Keni", "Mike", "Olaf", "Richard",
  26.     /* Mac team */
  27.     "Barton", "David", "Johnny", "Jon", "Jonathan", "Michael", "Rob",
  28.     "Tim", "Wang",
  29.     /* Atari team */
  30.     "Eric",
  31.     /* NT team */
  32.     "Michael",
  33.     /* OS/2 team */
  34.     "Timo",
  35.     /* VMS team */
  36.     "Joshua", "Pat",
  37.     ""};
  38.  
  39.  
  40. /* return a randomly chosen developer name */
  41. static const char *
  42. dev_name() 
  43. {
  44.     register int i, m = 0, n = SIZE(developers);
  45.     register struct monst *mtmp;
  46.     register boolean match;
  47.  
  48.     do {
  49.         match = FALSE;
  50.         i = rn2(n);
  51.         for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 
  52.         if(!is_mplayer(mtmp->data)) continue;
  53.         if(!strncmp(developers[i], NAME(mtmp),
  54.                            strlen(developers[i]))) {
  55.             match = TRUE;
  56.             break;
  57.             }
  58.         }
  59.         m++;
  60.     } while (match && m < 100); /* m for insurance */
  61.  
  62.     if (match) return NULL;
  63.     return(developers[i]);
  64. }
  65.  
  66. static void
  67. get_mplname(mtmp, nam)
  68. register struct monst *mtmp;
  69. char *nam;
  70. {
  71.     boolean fmlkind = is_female(mtmp->data);
  72.     const char *devnam;
  73.  
  74.     devnam = dev_name();
  75.     if (!devnam)
  76.         Strcpy(nam, fmlkind ? "Eve" : "Adam");
  77.     else if (fmlkind && !!strcmp(devnam, "Janet"))
  78.         Strcpy(nam, rn2(2) ? "Maud" : "Eve");
  79.     else Strcpy(nam, devnam);
  80.  
  81.     if (fmlkind || !strcmp(nam, "Janet"))
  82.         mtmp->female = 1;
  83.     else
  84.         mtmp->female = 0;
  85.     Strcat(nam, " the ");
  86.     Strcat(nam, rank_of((unsigned)rn1(12, 20), 
  87.                highc(mtmp->data->mname[0]), (boolean)mtmp->female));
  88. }
  89.  
  90. static void
  91. mk_mplayer_armor(mon, range1, range2)
  92. struct monst *mon;
  93. int range1, range2;
  94. {
  95.     struct obj *obj;
  96.  
  97.     obj = mksobj(rnd_class(range1, range2), FALSE, FALSE);
  98.     if (!rn2(3)) obj->oerodeproof = 1;
  99.     if (!rn2(3)) curse(obj);
  100.     if (!rn2(3)) bless(obj);
  101.     /* Most players who get to the endgame who have cursed equipment
  102.      * have it because the wizard or other monsters cursed it, so its
  103.      * chances of having plusses is the same as usual....
  104.      */
  105.     obj->spe = rn2(10) ? (rn2(3) ? rn2(5) : rn1(4,4)) : -rnd(3);
  106.     mpickobj(mon, obj);
  107. }
  108.  
  109. struct monst *
  110. mk_mplayer(ptr, x, y, special)
  111. register struct permonst *ptr;
  112. xchar x, y;
  113. register boolean special;
  114. {
  115.     register struct monst *mtmp;
  116.     char nam[PL_NSIZ];
  117.  
  118.     if(!is_mplayer(ptr)) 
  119.         return((struct monst *)0);
  120.  
  121.     if(MON_AT(x, y))
  122.         rloc(m_at(x, y)); /* insurance */
  123.  
  124.     if(!In_endgame(&u.uz)) special = FALSE;
  125.  
  126.     if ((mtmp = makemon(ptr, x, y)) != 0) {
  127.         int weapon, quan;
  128.         struct obj *otmp;
  129.  
  130.         mtmp->m_lev = (special ? rn1(8,12) : rnd(16));
  131.         mtmp->mhp = mtmp->mhpmax = (special ?
  132.                           (d((int)mtmp->m_lev,10) + 30 + rnd(30)) :
  133.                           (d((int)mtmp->m_lev,10) + 30));
  134.         if(special) {
  135.             get_mplname(mtmp, nam);
  136.             mtmp = christen_monst(mtmp, nam);
  137.         }
  138.         mtmp->mpeaceful = 0;
  139.         set_malign(mtmp); /* peaceful may have changed again */
  140.         if(special && In_endgame(&u.uz))
  141.         /* that's why they are "stuck" in the endgame :-) */
  142.         (void)mongets(mtmp, FAKE_AMULET_OF_YENDOR);
  143.         switch(monsndx(ptr)) {
  144.         case PM_ARCHEOLOGIST:
  145.             weapon = BULLWHIP;
  146.             break;
  147.         case PM_BARBARIAN:
  148.             weapon = rn2(2) ? TWO_HANDED_SWORD : BATTLE_AXE;
  149.             break;
  150.         case PM_CAVEMAN:
  151.         case PM_CAVEWOMAN:
  152.             weapon = CLUB;
  153.             break;
  154.         case PM_ELF:
  155.             weapon = ELVEN_SHORT_SWORD;
  156.             break;
  157.         case PM_HEALER:
  158.             weapon = SCALPEL;
  159.             break;
  160.         case PM_KNIGHT:
  161.             weapon = LONG_SWORD;
  162.             break;
  163.         case PM_PRIEST:
  164.         case PM_PRIESTESS:
  165.             weapon = MACE;
  166.             break;
  167.         case PM_ROGUE:
  168.             weapon = SHORT_SWORD;
  169.             break;
  170.         case PM_SAMURAI:
  171.             weapon = KATANA;
  172.             break;
  173. #ifdef TOURIST
  174.         case PM_TOURIST:
  175.             weapon = 0;
  176.             break;
  177. #endif
  178.         case PM_VALKYRIE:
  179.             weapon = LONG_SWORD;
  180.             break;
  181.         case PM_WIZARD:
  182.             weapon = ATHAME;
  183.             break;
  184.         default: impossible("bad mplayer monster");
  185.             weapon = 0;
  186.             break;
  187.         }
  188.         if (rn2(2) && weapon)
  189.         otmp = mksobj(weapon, TRUE, FALSE);
  190.         else
  191.         otmp = mksobj(rn2(2) ? LONG_SWORD : 
  192.                   rnd_class(SPEAR, BULLWHIP), TRUE, FALSE);
  193.         otmp->spe = (special ? rn1(5,4) : rn2(4));
  194.         if (!rn2(3)) otmp->oerodeproof = 0;
  195.         if(special) {
  196.             /* probably the player got most artifacts anyway. */
  197.             if(In_endgame(&u.uz) && rn2(2)) 
  198.                   otmp = mk_artifact(otmp, A_NONE);
  199.             mpickobj(mtmp, otmp);
  200.             if (!rn2(10))
  201.             (void) mongets(mtmp, rn2(3) ? LUCKSTONE : LOADSTONE);
  202.             if (rn2(8))
  203.             mk_mplayer_armor(mtmp, ELVEN_LEATHER_HELM, HELM_OF_TELEPATHY);
  204.             if (!rn2(3))
  205.             mk_mplayer_armor(mtmp, GRAY_DRAGON_SCALE_MAIL,
  206.             YELLOW_DRAGON_SCALE_MAIL);
  207.             else if (rn2(15))
  208.             mk_mplayer_armor(mtmp, PLATE_MAIL, CHAIN_MAIL);
  209.             if (rn2(8))
  210.             mk_mplayer_armor(mtmp, ELVEN_SHIELD, 
  211.                                SHIELD_OF_REFLECTION);
  212.             if (rn2(8))
  213.             mk_mplayer_armor(mtmp, LEATHER_GLOVES, 
  214.                                GAUNTLETS_OF_DEXTERITY);
  215.             if (rn2(8))
  216.             mk_mplayer_armor(mtmp, LOW_BOOTS, LEVITATION_BOOTS);
  217. #ifdef MUSE
  218.             /* Not clear what to do without MUSE. */
  219.             m_dowear(mtmp, TRUE);
  220. #endif
  221.             quan = rn2(3) ? rn2(3) : rn2(16);
  222.             while(quan--)
  223.             (void)mongets(mtmp, rnd_class(DILITHIUM_CRYSTAL, JADE));
  224.             /* To get the gold "right" would mean a player can double his */
  225.             /* gold supply by killing one mplayer.  Not good. */
  226.             mtmp->mgold = rn2(1000);
  227.             quan = rn2(10);
  228.             while(quan--)
  229.             mpickobj(mtmp, mkobj(RANDOM_CLASS, FALSE));
  230.         }
  231. #ifdef MUSE
  232.         quan = rnd(3);
  233.         while(quan--)
  234.         (void)mongets(mtmp, rnd_offensive_item(mtmp));
  235.         quan = rnd(3);
  236.         while(quan--)
  237.         (void)mongets(mtmp, rnd_defensive_item(mtmp));
  238.         quan = rnd(3);
  239.         while(quan--)
  240.         (void)mongets(mtmp, rnd_misc_item(mtmp));
  241. #endif
  242.     }
  243.  
  244.     return(mtmp);
  245. }
  246.  
  247. /* create the indicated number (num) of monster-players,
  248.  * randomly chosen, and in randomly chosen (free) locations
  249.  * on the level.  If "special", the size of num should not
  250.  * be bigger than the number of _non-repeated_ names in the
  251.  * developers array, otherwise a bunch of Adams and Eves will
  252.  * fill up the overflow.
  253.  */
  254. void
  255. create_mplayers(num, special)
  256. register int num;
  257. boolean special;
  258. {
  259.     register int pm, x, y;
  260.  
  261.     while(num) {
  262.         int tryct = 0;
  263.  
  264.         /* roll for character class */
  265.         pm = PM_ARCHEOLOGIST + rn2(PM_WIZARD - PM_ARCHEOLOGIST + 1);
  266.  
  267.         /* roll for an available location */
  268.         do {
  269.             x = rn1(COLNO-4, 2);
  270.             y = rnd(ROWNO-2);
  271.         } while(!goodpos(x, y, (struct monst *)0, &mons[pm]) ||
  272.              tryct++ >= 50);
  273.  
  274.         /* if pos not found in 50 tries, don't bother to continue */
  275.         if(tryct > 50) return;
  276.  
  277.         (void) mk_mplayer(&mons[pm], (xchar)x, (xchar)y, special);
  278.         num--;
  279.     }
  280. }
  281.  
  282. void
  283. mplayer_talk(mtmp)
  284. register struct monst *mtmp;
  285. {
  286.     static const char *same_class_msg[3] = {
  287.         "I can't win, and neither will you!",
  288.         "You don't deserve to win!",
  289.         "Mine should be the honor, not yours!",
  290.     },          *other_class_msg[3] = {
  291.         "The low-life wants to talk, eh?",
  292.         "Fight, scum!",
  293.         "Here is what I have to say!",
  294.     };
  295.  
  296.     if(mtmp->mpeaceful) return; /* will drop to humanoid talk */
  297.  
  298.     pline("Talk? -- %s", pl_character[0] == highc(*mtmp->data->mname) ?
  299.         same_class_msg[rn2(3)] : other_class_msg[rn2(3)]);
  300. }
  301.  
  302. /*mplayer.c*/
  303.